/*
* License:  This  program  is  free  software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published by
* the  Free Software Foundation; either version 3 of the License, or (at your
* option)  any later version. This program is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*/

package pcgen.CharacterViewer;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.TreeMap;

import org.apache.commons.lang.StringUtils;

import pcgen.CharacterViewer.resources.GameResource;

import android.app.Activity;
import android.content.Context;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.Browser;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.inputmethod.InputMethodManager;
import android.webkit.URLUtil;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.RadioButton;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.Toast;

import android.view.Menu;
import android.view.MenuItem;

public class SelectGameResourceDialogActivity extends AppListActivity
{
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) 
    {
        if ((keyCode == KeyEvent.KEYCODE_BACK)) 
        {
            _buttonSelect.setEnabled(false);

//            if (layoutCreate.getVisibility() == View.VISIBLE) 
//            {
//                layoutCreate.setVisibility(View.GONE);
//                layoutSelect.setVisibility(View.VISIBLE);
//            } 
//            else 
            {
                if (_currentPath.equals(ROOT))
                	return super.onKeyDown(keyCode, event);

                getDir(_parentPath);
            }

            return true;
        } 
        
        return super.onKeyDown(keyCode, event);
    }
    
    @Override
    protected void initialize(Bundle savedInstanceState)
    {
        super.initialize(savedInstanceState);
        
        setResult(RESULT_CANCELED, getIntent());
        
        _modeSelection = ModesSelection.valueOf(getIntent().getStringExtra(SETTING_SELECTION_MODE));

        setContentView(R.layout.dialog_resource_select);
        _textPath = (TextView) findViewById(R.id.text_path);
        _textInputName = (TextView)findViewById(R.id.input_name);

        //inputManager = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
        
        final Activity reference = this;
        
        _buttonModeExternal = (RadioButton)findViewById(R.id.button_mode_external);
        _buttonModeExternal.setOnClickListener(new OnClickListener() 
        {
            public void onClick(View v) 
            {
            	setDisplayMode(ModesDisplay.External);
            }
        });
        
        _buttonModeLocal = (RadioButton)findViewById(R.id.button_mode_local);
        _buttonModeLocal.setOnClickListener(new OnClickListener() 
        {
            public void onClick(View v) 
            {
            	setDisplayMode(ModesDisplay.Local);
            }
        });

        _layoutExternal = (View)findViewById(R.id.layout_external);
        _layoutExternal.setVisibility(View.GONE);
        _layoutLocal = (View)findViewById(R.id.layout_local);
        _layoutLocal.setVisibility(View.GONE);
        _layoutModeSelection = (View)findViewById(R.id.layout_mode_selection);
        _layoutModeSelection.setVisibility(View.GONE);
        _layoutSelect = (View)findViewById(R.id.layout_select);
        _layoutSelect.setVisibility(View.GONE);
        
        _textInputAddress = (AutoCompleteTextView)findViewById(R.id.input_address);
		
        Cursor bookmarksCursor =  managedQuery(
        		android.provider.Browser.BOOKMARKS_URI, 
				new String[] { Browser.BookmarkColumns.TITLE , Browser.BookmarkColumns.URL }, 
				android.provider.Browser.BookmarkColumns.BOOKMARK, 
				null, 
				null);
		int indexUrl = bookmarksCursor.getColumnIndex(Browser.BookmarkColumns.URL);
		bookmarksCursor.moveToFirst();
		ArrayList<String> bookmarks = new ArrayList<String>();
        while (bookmarksCursor.isAfterLast() == false) 
		{
			bookmarks.add(bookmarksCursor.getString(indexUrl));
			bookmarksCursor.moveToNext();
		}
        
        _textInputAddress.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_dropdown_item_1line, bookmarks));
        
    	if (_modeSelection == ModesSelection.Character)
    		setDisplayMode(ModesDisplay.Character);
    	else
    		setDisplayMode(ModesDisplay.External);

        _buttonSelect = (Button)findViewById(R.id.button_select);
        //_buttonSelect.setEnabled(false);
        _buttonSelect.setOnClickListener(new OnClickListener() 
        {
            public void onClick(View v) 
            {
            	if ((_modeSelection == ModesSelection.Character) ||
            		((_modeSelection == ModesSelection.Other) && (_modeDisplay == ModesDisplay.Local)))
            	{
	                if (_selectedFile == null)
	                {
	                	Toast.makeText(reference, String.format(reference.getString(R.string.validation_required), reference.getString(R.string.dialog_validation_select_game_resource_file)), Toast.LENGTH_SHORT).show();
	                    return;
	                }
	                
	                getIntent().putExtra(RESULT_PATH, _selectedFile.getPath());
	                
	                if (_modeSelection == ModesSelection.Character)
	                	getIntent().putExtra(RESULT_RESOURCE_TYPE, GameResource.ResourceTypes.Character.toString());
	                else
	                {
	                	if (_selectedFile.getName().endsWith(".pdf"))
		                	getIntent().putExtra(RESULT_RESOURCE_TYPE, GameResource.ResourceTypes.Pdf.toString());
	                	else
		                	getIntent().putExtra(RESULT_RESOURCE_TYPE, GameResource.ResourceTypes.Web.toString());
	                }
            	}
            	else
            	{
            		String address = _textInputAddress.getText().toString();
            		if (StringUtils.isEmpty(address))
                    {
                    	Toast.makeText(reference, String.format(reference.getString(R.string.validation_required), reference.getString(R.string.dialog_validation_select_game_resource_address)), Toast.LENGTH_SHORT).show();
                    	return;
                    }
            		
            		if (!URLUtil.isValidUrl(address) || !URLUtil.isHttpUrl(address) || !URLUtil.isHttpUrl(address))
            		{
            			Toast.makeText(reference, reference.getString(R.string.dialog_validation_select_game_invalid_url), Toast.LENGTH_SHORT).show();
                    	return;
            		}
	                getIntent().putExtra(RESULT_PATH, address);
	                getIntent().putExtra(RESULT_RESOURCE_TYPE, GameResource.ResourceTypes.Web.toString());
            	}
                
                String name = _textInputName.getText().toString();
                
                if (StringUtils.isEmpty(name))
                {
                	Toast.makeText(reference, String.format(reference.getString(R.string.validation_required), reference.getString(R.string.dialog_validation_select_game_resource_name)), Toast.LENGTH_SHORT).show();
                	return;
                }
                
                if (!getApplicationEx().validateNameCharacters(name))
                {
                	Toast.makeText(reference, reference.getString(R.string.validation_name_invalid_characters), Toast.LENGTH_SHORT).show();
                	return;
                }
            	
                getIntent().putExtra(RESULT_NAME, name);
                setResult(RESULT_OK, getIntent());
                finish();
            }
        });

        final Button cancelButton = (Button) findViewById(R.id.button_cancel);
        //cancelButton.setEnabled(true);
        cancelButton.setOnClickListener(new OnClickListener() 
        {
            public void onClick(View v) 
            {
                setResult(RESULT_CANCELED, getIntent());
                finish();
            }
        });

//        final Button newButton = (Button) findViewById(R.id.fdButtonNew);
//        newButton.setOnClickListener(new OnClickListener() 
//        {
//            public void onClick(View v) 
//            {
//                setCreateVisible(v);
//
//                mFileName.setText("");
//                mFileName.requestFocus();
//            }
//        });

//        _selectionMode = getIntent().getIntExtra(SELECTION_MODE, MODE_CREATE);
//        if (_selectionMode == MODE_OPEN)
//        	newButton.setEnabled(false);

//        _layoutSelect = (LinearLayout) findViewById(R.id.fdLinearLayoutSelect);
//        _layoutCreate = (LinearLayout) findViewById(R.id.fdLinearLayoutCreate);
//        layoutCreate.setVisibility(View.GONE);

//        final Button cancelButton = (Button) findViewById(R.id.fdButtonCancel);
//        cancelButton.setOnClickListener(new OnClickListener() 
//        {
//            public void onClick(View v) 
//            {
//                    setSelectVisible(v);
//            }
//        });
        
//        final Button createButton = (Button) findViewById(R.id.fdButtonCreate);
//        createButton.setOnClickListener(new OnClickListener() 
//        {
//            public void onClick(View v) 
//            {
//                if (mFileName.getText().length() > 0) 
//                {
//                    getIntent().putExtra(RESULT_PATH, currentPath + "/" + mFileName.getText());
//                    setResult(RESULT_OK, getIntent());
//                    finish();
//                }
//            }
//        });

        String startPath = getIntent().getStringExtra(SETTING_START_PATH);
        if (startPath != null)
        	getDir(startPath);
        else
        	getDir(ROOT);
    }
    
    @Override
    public boolean dispatchTouchEvent(MotionEvent event) 
    {
        View view = getCurrentFocus();
        boolean ret = super.dispatchTouchEvent(event);

        if (view instanceof EditText) 
        {
            View w = getCurrentFocus();
            int scrcoords[] = new int[2];
            w.getLocationOnScreen(scrcoords);
            float x = event.getRawX() + w.getLeft() - scrcoords[0];
            float y = event.getRawY() + w.getTop() - scrcoords[1];

            //Log.d("Activity", "Touch event "+event.getRawX()+","+event.getRawY()+" "+x+","+y+" rect "+w.getLeft()+","+w.getTop()+","+w.getRight()+","+w.getBottom()+" coords "+scrcoords[0]+","+scrcoords[1]);
            if (event.getAction() == MotionEvent.ACTION_UP && (x < w.getLeft() || x >= w.getRight() || y < w.getTop() || y > w.getBottom()) ) 
            { 
                InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
                imm.hideSoftInputFromWindow(getWindow().getCurrentFocus().getWindowToken(), 0);
            }
        }
        
        return ret;
    }

    @Override
    protected void onListItemClick(ListView l, View v, int position, long id)
    {
        File file = new File(path.get(position));

        //setSelectVisible(v);

        if (file.isDirectory()) 
        {
            _buttonSelect.setEnabled(false);
            if (file.canRead()) 
            {
                _lastPositions.put(_currentPath, position);
                getDir(path.get(position));
            } 
            else 
            {
            	Toast.makeText(this, getString(R.string.dialog_error_select_game_resource_cant_read_folder), Toast.LENGTH_SHORT).show();
                
//                new AlertDialog.Builder(this)
//                    .setIcon(R.drawable.icon)
//                    .setTitle("[" + file.getName() + "] " + getText(R.string.dialog_resource_select_cant_read_folder))
//                    .setPositiveButton("OK",
//                    	new DialogInterface.OnClickListener() 
//                    	{
//                    		public void onClick(DialogInterface dialog, int which) 
//                    		{
//                    		}
//                         })
//                    .show();
            }
        } 
        else 
        {
            _selectedFile = file;
            v.setSelected(true);
            _buttonSelect.setEnabled(true);
            
            if (StringUtils.isEmpty(_textInputName.getText().toString()))
    		{
            	String fileName = file.getName();
            	String[] values = fileName.split("\\.");
            	if (values.length > 0)
            		_textInputName.setText(values[0]);
    		}
        }
    }

    private void addItem(String fileName, int imageId) 
    {
        HashMap<String, Object> item = new HashMap<String, Object>();
        item.put(ITEM_KEY, fileName);
        item.put(ITEM_IMAGE, imageId);
        _list.add(item);
    }

    private void getDir(String dirPath) 
    {
        boolean useAutoSelection = dirPath.length() < _currentPath.length();

        getDirImpl(dirPath);

        Integer position = _lastPositions.get(_parentPath);
        if (position != null && useAutoSelection)
        	getListView().setSelection(position);

    }

    private void getDirImpl(final String dirPath) 
    {
        _currentPath = dirPath;

        final List<String> item = new ArrayList<String>();
        path = new ArrayList<String>();
        _list = new ArrayList<HashMap<String, Object>>();

        File f = new File(_currentPath);
        File[] files = f.listFiles();
        if (files == null) 
        {
            _currentPath = ROOT;
            f = new File(_currentPath);
            files = f.listFiles();
        }
        _textPath.setText(getText(R.string.dialog_text_select_game_resource_location) + ": " + _currentPath);

        if (!_currentPath.equals(ROOT)) 
        {
            item.add(ROOT);
            addItem(ROOT, R.drawable.folder);
            path.add(ROOT);

            item.add("../");
            addItem("../", R.drawable.folder);
            path.add(f.getParent());
            _parentPath = f.getParent();
        }

        TreeMap<String, String> dirsMap = new TreeMap<String, String>();
        TreeMap<String, String> dirsPathMap = new TreeMap<String, String>();
        TreeMap<String, String> filesMap = new TreeMap<String, String>();
        TreeMap<String, String> filesPathMap = new TreeMap<String, String>();
        for (File file : files) 
        {
        	if (!file.canRead())
        		continue;
        	
            if (file.isDirectory()) 
            {
                String dirName = file.getName();
                if (dirName.startsWith("."))
                	continue;
                
                dirsMap.put(dirName, dirName);
                dirsPathMap.put(dirName, file.getPath());
            } 
            else 
            {
            	String name = file.getName();
            	String[] extensions = new String[] { ".html", ".htm" };
            	if (_modeSelection == ModesSelection.Other)
            		extensions = new String[] {  ".html", ".htm", ".pdf" };
            	
            	boolean valid = false;
            	for (String extension : extensions)
            	{
            		if (name.endsWith(extension))
            		{
            			valid = true;
            			break;
            		}
            	}
            	
            	if (valid)
            	{
	                filesMap.put(file.getName(), file.getName());
	                filesPathMap.put(file.getName(), file.getPath());
            	}
            }
        }
        item.addAll(dirsMap.tailMap("").values());
        item.addAll(filesMap.tailMap("").values());
        path.addAll(dirsPathMap.tailMap("").values());
        path.addAll(filesPathMap.tailMap("").values());

        SimpleAdapter fileList = new SimpleAdapter(this, _list, R.layout.dialog_resource_select_row,
            new String[] { ITEM_KEY, ITEM_IMAGE }, new int[] { R.id.fdrowtext, R.id.fdrowimage });

        for (String dir : dirsMap.tailMap("").values())
        	addItem(dir, R.drawable.folder);

        for (String file : filesMap.tailMap("").values())
        	addItem(file, R.drawable.file);

        fileList.notifyDataSetChanged();

        setListAdapter(fileList);
    }

//    private void setCreateVisible(View v) 
//    {
//        layoutCreate.setVisibility(View.VISIBLE);
//        layoutSelect.setVisibility(View.GONE);
//
//        inputManager.hideSoftInputFromWindow(v.getWindowToken(), 0);
//        selectButton.setEnabled(false);
//    }
//
//    private void setSelectVisible(View v) 
//    {
//        layoutCreate.setVisibility(View.GONE);
//        layoutSelect.setVisibility(View.VISIBLE);
//
//        inputManager.hideSoftInputFromWindow(v.getWindowToken(), 0);
//        selectButton.setEnabled(false);
//    }
    
    private void setDisplayMode(ModesDisplay mode)
    {
    	_modeDisplay = mode;
    	
        if (mode == ModesDisplay.Character)
    	{
        	_layoutSelect.setVisibility(View.VISIBLE);
            _layoutLocal.setVisibility(View.VISIBLE);
            _textInputName.requestFocus();
    	}
    	else
    	{
    		_layoutModeSelection.setVisibility(View.VISIBLE);
	        _layoutLocal.setVisibility(View.GONE);
	        _layoutExternal.setVisibility(View.GONE);
        	_layoutSelect.setVisibility(View.GONE);
	    	if (mode == ModesDisplay.External)
	    	{
	    		_buttonModeExternal.setChecked(true);
	        	_layoutSelect.setVisibility(View.VISIBLE);	
	            _layoutExternal.setVisibility(View.VISIBLE);
	            _textInputAddress.requestFocus();
	    	}
	    	else if (mode == ModesDisplay.Local)
	    	{
	    		_buttonModeLocal.setChecked(true);
	        	_layoutSelect.setVisibility(View.VISIBLE);	
	            _layoutLocal.setVisibility(View.VISIBLE);
	            _textInputName.requestFocus();
	    	}
    	}
    }

    private static final String ITEM_KEY = "key";
    private static final String ITEM_IMAGE = "image";
    private static final String ROOT = "/";

    public static final String RESULT_RESOURCE_TYPE = "result.resource.type";
    public static final String RESULT_NAME = "result.name";
    public static final String RESULT_PATH = "result.path";
    public static final String SETTING_SELECTION_MODE = "setting.selection.mode";
    public static final String SETTING_START_PATH = "setting.start.path";
    
    public static final int MODE_CREATE = 0;
    public static final int MODE_OPEN = 1;

    private List<String> path = null;
    private TextView _textPath;
    private TextView _textInputName;
    private ArrayList<HashMap<String, Object>> _list;

    private RadioButton _buttonModeLocal;
    private RadioButton _buttonModeExternal;
    private Button _buttonSelect;
    
    private View _layoutLocal;
    private View _layoutExternal;
    private View _layoutModeSelection;
    private View _layoutSelect;
    
    private AutoCompleteTextView _textInputAddress;

//    private LinearLayout layoutSelect;
//    private LinearLayout layoutCreate;
//    private InputMethodManager inputManager;
    private String _parentPath;
    private String _currentPath = ROOT;

//    private int _selectionMode = MODE_CREATE;

    private File _selectedFile;
    private HashMap<String, Integer> _lastPositions = new HashMap<String, Integer>();
    
    private ModesDisplay _modeDisplay;
    private ModesSelection _modeSelection;
    
    private enum ModesDisplay
    {
    	Character,
    	Local,
    	External
    }
    
    public enum ModesSelection
    {
    	Character,
    	Other
    }
}